import { VisualEditorBlockData } from "@/components/visual-editor/visualEditor.utils"
import { onUnmounted } from "vue"
import {KeyboardCode} from './keyboard-code'
export interface CommandExecute {
  undo?: () => void;
  redo: () => void;
}
/** 自定义命令 */
export interface Command {
  name: string;
  keyboard: string[];
  followQueue?: boolean;
  init?: () => (() => void | undefined);
  data?: {
    before: null | VisualEditorBlockData[];
    after: null | VisualEditorBlockData[];
  };
  execute: (...args: any[]) => CommandExecute;
}

export function useCommand(){
  const state = {
    /** 命令数组 */
    commands : {} as Record<string, (...args: any[]) => void>, 
    /** execute返回return的数组队列 */
    queue: [] as CommandExecute[],
    /** execute数组队列的下标 */
    current: -1,
    /** command的数组容器 */
    commandArray: [] as Command[],
    /** 事件销毁的数组容器 */
    destoryList: [] as ((() => void) | undefined)[]
  }
  const keyboardEvent = (()=>{
    const onKeyDown = (e: KeyboardEvent)=>{
        /** 快捷键触发时点击的元素是body的话，不触发自定义快捷键 */
        if(document.activeElement !== document.body){
          return
        }
        /** ctrlKey:control,metaKey:command,shiftKey:shift */
        const {ctrlKey,keyCode,shiftKey,metaKey,altKey} = e
        const strKey: string[] = []
        if(ctrlKey || metaKey)strKey.push('ctr')
        if(shiftKey) strKey.push('shift')
        if(altKey) strKey.push('alt')
        if(keyCode) strKey.push(KeyboardCode[keyCode])
        /** 将按下的键盘快捷键收集后进行匹配，执行匹配到的快捷命令 */
        state.commandArray.forEach(({name,keyboard})=>{
          if(!keyboard || keyboard.length===0) return
          if(keyboard.indexOf(strKey.join('+')) > -1){
            state.commands[name]()
            e.preventDefault()
            e.stopPropagation()
          }
        })
    }
    const init = ()=>{
      window.addEventListener('keydown',onKeyDown)
      return ()=>window.removeEventListener('keydown',onKeyDown)
    }
    return {
      init
    }
  })()

  /** 初始化 */
  const init = ()=>{
    state.commandArray.forEach(command => !!command.init && state.destoryList.push(command.init()))
    state.destoryList.push(keyboardEvent.init())
  }
  /** 销毁事件  */
  onUnmounted(()=>{
    state.destoryList.forEach(fn => !!fn && fn())
  })

  return {
    state,
    init,
    /** 注册命令 */
    registry(command: Command){
      state.commandArray.push(command)
      state.commands[command.name] = (...args) =>{
        const {undo,redo} = command.execute(...args)        
        if(command.followQueue){
          state.queue.push({undo, redo})
          state.current++
        }
        !!redo && redo()
      }
      // !!command.init && command.init()
    }
  }
}